package com.hicorp.segment.security.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hicorp.segment.security.config.SecurityConfig;
import com.hicorp.segment.utils.JWTUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 访问过滤器
 * </p>
 *
 * @author qy
 * @since 2019-11-08
 */
public class TokenAuthenticationFilter extends BasicAuthenticationFilter {
    private final JWTUtil jwtUtil;

    public TokenAuthenticationFilter(AuthenticationManager authManager, JWTUtil jwtUtil) {
        super(authManager);
        this.jwtUtil = jwtUtil;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        String token = req.getHeader("token");
        if (token == null || token.isEmpty()) {
            chain.doFilter(req, res);
            return ;
        }
            UsernamePasswordAuthenticationToken authentication;
            try {
                authentication = getAuthentication(token);
                if (authentication != null) {
                    if(!jwtUtil.isTokenExpired(token))
                    {SecurityContextHolder.getContext().setAuthentication(authentication);}
                    else{
                        chain.doFilter(req, res);
                        return ;
                    }
                }
            } catch (Exception e) {
                Map<String, Object> map = new HashMap<>();
                map.put("code", 403);
                map.put("msg", "身份过期，请重新登录");
                res.setContentType("application/json;charset=utf-8");
                PrintWriter out = res.getWriter();
                out.write(new ObjectMapper().writeValueAsString(map));
                out.flush();
                out.close();
            }
            chain.doFilter(req, res);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(String token) {
        // spring security 权限验证List
            String userName = jwtUtil.getUsernameFromToken(token);
            if (!userName.isEmpty()&&SecurityConfig.userMap.get(userName)!=null) {
                return new UsernamePasswordAuthenticationToken(userName, token, SecurityConfig.userMap.get(userName));
            }
            return null;
    }
   }